package com.cgah

import java.util.Formatter.DateTime

/**
 *
Listing Domain Requirements
A Listing is an item for sale at AuctionHaus. Listings have the following requirements:
Done - L-1: Listings have the following required fields: name, end date/time, and starting bid price (unit test)
Done - L-2: Listings have the following optional fields: description (unit test)
Done - L-3: Listings are required to have a seller (Customer) (unit test)

// TODO? L-4 and L-5 really? another failed requirement
- L-4: Updating a Listing should not update the seller's information (integration test)
- L-5: Updating a seller's information should not modify any properties of that seller's listings (integration test)

Done - L-6: Listing descriptions must be less than 256 characters (integration test)
TODO : add validator? - L-7: Listing end date/time must be in the future (integration test)
Done - L-8: Listing name must be less than 64 characters (integration test)
Done - L-9: Listing has a nullable field for the winner (Customer) (integration test)
Done - B-4: A Listing has a list of Bids for that Listing (integration test)
 */

class Listing {
	String name;
	Date endDateTime;
	Float startingBidPrice;
	String description;
    Date createdDateTime;
	// ??: updating listing does not update customer info ? why would it do this, if it does, then grails is crap! and should be trashed.
	// ??: updating seller, does not affect any of listing property? same comment as above
    // relations
    // TODO: Fails L5. Need to manually add database propagation constraints.
    static belongsTo = [seller:Customer];
	static hasOne = [winner:Customer];
	// ?:  ensure bids are saved when listing is saved.
    static hasMany = [bids:Bid];

    static transients = ['latestBid'];

    static constraints = {
	    // required fields
	    name(nullable:false, size: 1..64);
	    endDateTime(nullable:false,
                validator: {theEndDateTime,  thisObject ->
                    Calendar now = Calendar.getInstance();
                    now.add(Calendar.MINUTE, 5);
                    if (theEndDateTime.time < now.timeInMillis) {
                        return "The listing must last at least 5 mins."
                    }
                    return true;
                }
        );
	    startingBidPrice(nullable:false);
        seller(nullable: false);

	    // optional fields
	    description(nullable:true, size: 0..254);
	    winner(nullable: true);
        bids(nullable: true);

    }


    // L-3: The detail page for the listing shows the most recent bid
    Bid getLatestBid() {
        if (!bids.empty()) {
            return bids.max {it.dateTime.time};
        } else {
            return null;
        }
    }

}

